package com.xxx.reportingsystem.controller;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xxx.common.Code;
import com.xxx.common.Result;
import com.xxx.pojo.*;
import com.xxx.reportingsystem.dto.UserDto;
import com.xxx.service.UserOperateService;
import com.xxx.reportingsystem.service.UserRoleService;
import com.xxx.reportingsystem.service.UserService;
import com.xxx.service.DepartmentService;
import com.xxx.utils.ExportUtil;
import com.xxx.utils.IpUtil;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@RequestMapping("/user")
@RestController
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private UserOperateService userOperateService;

    @Autowired
    private DepartmentService departmentService;


    @Transactional
    @PostMapping("/login")
    public Result userLogin(@RequestBody User user, HttpServletRequest httpServletRequest){
        String ipAddr = IpUtil.getIpAddr(httpServletRequest);
        Result login = userService.login(user,ipAddr);
        return login;
    }
    @Transactional
    @GetMapping("/logout")
    public Result userLoginOut(){
        return userService.loginOut();
    }

    @Transactional
    @PostMapping("/add")
    @PreAuthorize("hasAnyAuthority('sys:add:user')")
    public Result userAdd(@RequestBody User user, @RequestParam(required = false,value = "roles") List<Integer> roles){
        if (Objects.isNull(user)){
            return Result.error(Code.USER_ERROR,"用户为空,添加失败!~");
        }

        if (roles != null && roles.size()>0){
            for (Integer role : roles) {
                UserRole userRole = new UserRole(user.getUserId(), role, null, null);
                boolean save = userRoleService.save(userRole);
            }
        }
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        user.setCreateUser(loginUser.getUser().getName());
        user.setUpdateUser(loginUser.getUser().getName());
        //获取系统当前时间
        LocalDateTime now = LocalDateTime.now();
        user.setCreateTime(now);
        user.setUpdateTime(now);
        String password = new BCryptPasswordEncoder().encode(user.getPassword());
        user.setPassword(password);
        boolean save = userService.save(user);
        if (save){
            userOperateService.addLogManage("用户管理","添加用户","添加");
            return Result.success("添加成功!~");
        }
        return Result.error(Code.USER_ERROR,"添加失败!~");
    }

    @Transactional
    @PostMapping("/select")
    public Result selectUserByCondition(@RequestBody User user1,@RequestParam("current") Integer current,@RequestParam("size") Integer size){
        if (Objects.isNull(user1)){
            throw new RuntimeException("数据传输格式错误!~");
        }

        IPage iPage = new Page(current,size);
        IPage page = userService.page(iPage);
        List<User> user = page.getRecords();
        List<UserDto> list = user.stream().map(o -> {
            Department department = departmentService.getById(o.getDepartmentId());
            UserDto userDto = new UserDto();
            BeanUtils.copyProperties(o, userDto);
            userDto.setDepartment(department);
            return userDto;
        }).collect(Collectors.toList());
        HashMap<String, Object> map = new HashMap<>();
        map.put("list",list);
        map.put("total", page.getTotal());
        return Result.success("",map);
    }

    @Transactional
    @PutMapping("/update")
    @PreAuthorize("hasAnyAuthority('sys:update:user')")
    public Result userUpdate(@RequestBody User user){
        if (Objects.isNull(user)){
            throw new RuntimeException("数据传输格式错误!~");
        }
        String password = new BCryptPasswordEncoder().encode(user.getPassword());
        user.setPassword(password);
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        user.setUpdateUser(loginUser.getUser().getName());
        user.setUpdateTime(LocalDateTime.now());
        boolean b = userService.updateById(user);
        if (!b){
            return Result.error("修改失败!");
        }
        userOperateService.addLogManage("用户管理","修改用户","修改");
        return Result.success("修改成功!");
    }

    @Transactional
    @DeleteMapping("/delete")
    @PreAuthorize("hasAnyAuthority('sys:delete:user')")
    public Result deleteUserByIds(@RequestParam("userIds") List<Integer> userIds){
        boolean b = false;
        if (!Objects.isNull(userIds)){
            for (Integer userId : userIds) {
                b = userService.removeById(userId);
                userRoleService.removeById(userId);
            }
        }
        if (!b){
            return Result.error("删除失败!");
        }
        userOperateService.addLogManage("用户管理","删除用户","删除");
        return Result.success("删除成功!");
    }

    @Transactional
    @GetMapping("/export")
    @PreAuthorize("hasAnyAuthority('sys:add:user')")
    public void exportUserExcel(HttpServletResponse response) {
        try {
            ExportUtil.setExcelResponseProp(response, "用户列表");
            List<User> userList = userService.list();
            EasyExcel.write(response.getOutputStream())
                    .head(User.class)
                    .excelType(ExcelTypeEnum.XLSX)
                    .sheet("用户列表")
                    .doWrite(userList);
            userOperateService.addLogManage("用户管理","导出用户","导出");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }



}
